home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 42 / Amiga Format AFCD42 (Issue 126, Aug 1999).iso / -serious- / programming / other / jikes / src / parser.cpp < prev    next >
C/C++ Source or Header  |  1999-05-14  |  24KB  |  785 lines

  1. // $Id: parser.cpp,v 1.3 1999/01/25 20:00:31 shields Exp $
  2. //
  3. // This software is subject to the terms of the IBM Jikes Compiler
  4. // License Agreement available at the following URL:
  5. // http://www.ibm.com/research/jikes.
  6. // Copyright (C) 1996, 1998, International Business Machines Corporation
  7. // and others.  All Rights Reserved.
  8. // You must accept the terms of that agreement to use this software.
  9. //
  10. #include "config.h"
  11. #include <assert.h>
  12. #include <iostream.h>
  13. #include "parser.h"
  14. #include "ast.h"
  15.  
  16. void Parser::ReallocateStacks()
  17. {
  18.     int old_stack_length = stack_length;
  19.  
  20.     stack_length += STACK_INCREMENT;
  21.     assert(stack_length <= SHRT_MAX);
  22.  
  23.     int *old_stack = stack; 
  24.     stack = (int *) memmove(new int[stack_length], stack, old_stack_length * sizeof(int));
  25.     delete [] old_stack;
  26.  
  27.     Location *old_location_stack = location_stack; 
  28.     location_stack = (Location *) memmove(new Location[stack_length], location_stack, old_stack_length * sizeof(Location));
  29.     delete [] old_location_stack;
  30.  
  31.     Ast **old_parse_stack = parse_stack;
  32.     parse_stack = (Ast **) memmove(new Ast *[stack_length], parse_stack, old_stack_length * sizeof(Ast *));
  33.     delete [] old_parse_stack;
  34.     parse_stack[old_stack_length] = NULL; // the first time through, we initialize parse_stack[0] to NULL !!!
  35.  
  36.     int *old_temp_stack = temp_stack;
  37.     temp_stack = (int *) memmove(new int[stack_length], temp_stack, old_stack_length * sizeof(int));
  38.     delete [] old_temp_stack;
  39.  
  40.     return;
  41. }
  42.  
  43.  
  44. AstListNode *Parser::AllocateListNode()
  45. {
  46.     AstListNode *p;
  47.  
  48.     if (free_list_nodes)
  49.     {
  50.         p = free_list_nodes;
  51.         free_list_nodes = free_list_nodes -> next;
  52.     }
  53.     else p = list_node_pool -> NewListNode();
  54.  
  55.     return p;
  56. }
  57.  
  58.  
  59. void Parser::FreeCircularList(AstListNode *tail)
  60. {
  61.     AstListNode *root = tail -> next;
  62.     tail -> next = free_list_nodes;
  63.     free_list_nodes = root;
  64.  
  65.     return;
  66. }
  67.  
  68.  
  69. AstPackageDeclaration *Parser::PackageHeaderParse(LexStream *lex_stream_, StoragePool *ast_pool_)
  70. {
  71.     AstPackageDeclaration *package_declaration = NULL;
  72.  
  73.     lex_stream_ -> Reset();
  74.  
  75.     if (lex_stream_ -> Kind(lex_stream_ -> Peek()) == TK_package)
  76.     {
  77.         ast_pool = ast_pool_;
  78.  
  79.         parse_package_header_only = true;
  80.         end_token = LexStream::INFINITY; // We are parsing the whole input and not just a segment.
  81.         lex_stream = lex_stream_;
  82.         Ast *ast = HeaderParse();
  83.         parse_package_header_only = false;
  84.  
  85.         if (ast)
  86.         {
  87.             AstCompilationUnit *compilation_unit = ast -> CompilationUnitCast();
  88.             if (compilation_unit && (! compilation_unit -> BadCompilationUnitCast()))
  89.                 package_declaration = compilation_unit -> package_declaration_opt;
  90.         }
  91.     }
  92.  
  93.     return package_declaration;
  94. }
  95.  
  96.  
  97. AstCompilationUnit *Parser::HeaderParse(LexStream *lex_stream_, StoragePool *ast_pool_)
  98. {
  99.     lex_stream_ -> Reset();
  100.  
  101.     body_pool = new StoragePool(lex_stream_ -> NumTokens());
  102.     ast_pool = (ast_pool_ ? ast_pool_ : body_pool);
  103.     list_node_pool = new StoragePool(lex_stream_ -> NumTokens());
  104.     free_list_nodes = NULL;
  105.     AstCompilationUnit *compilation_unit = NULL;
  106.  
  107.     parse_header_only = true;
  108.     end_token = LexStream::INFINITY; // We are parsing the whole input and not just a segment.
  109.     lex_stream = lex_stream_;
  110.     Ast *ast = HeaderParse();
  111.     parse_header_only = false;
  112.  
  113.     if (ast)
  114.     {
  115.         compilation_unit = ast -> CompilationUnitCast();
  116.         if (compilation_unit && (! compilation_unit -> BadCompilationUnitCast()))
  117.         {
  118.             if (compilation_unit -> NumTypeDeclarations() == 0)
  119.                 compilation_unit -> kind = Ast::EMPTY_COMPILATION;
  120.         }
  121. // STG:
  122. //      else delete ast;
  123. //
  124.     }
  125.  
  126.     //
  127.     // If we succesfully parsed a compilation unit, allocate a storage pool for it.
  128.     // Subtract the amount of space that's already been allocated for the headers
  129.     // from the estimate for the bodies.
  130.     //
  131.     if (compilation_unit)
  132.          compilation_unit -> ast_pool = body_pool;
  133.     else delete body_pool;
  134.  
  135.     delete list_node_pool; // free the pool of list nodes
  136.  
  137.     return compilation_unit;
  138. }
  139.  
  140.  
  141. Ast *Parser::HeaderParse()
  142. {
  143.     TokenObject curtok = lex_stream -> Gettoken();
  144.     int act = START_STATE,
  145.               current_kind = lex_stream -> Kind(curtok);
  146.  
  147. /*****************************************************************/
  148. /* Start parsing.                                                */
  149. /*****************************************************************/
  150.     state_stack_top = -1;
  151.  
  152.     //
  153.     // Process a terminal
  154.     // 
  155.     for (;;)
  156.     {
  157.         if (++state_stack_top >= stack_length)
  158.             ReallocateStacks();
  159.  
  160.         stack[state_stack_top] = act;
  161.         location_stack[state_stack_top] = Loc(curtok);
  162.  
  163.         act = t_action(act, current_kind, lex_stream);
  164.  
  165.         if (act <= NUM_RULES)
  166.             state_stack_top--; // make reduction look like a shift-reduce
  167.         else if (act > ERROR_ACTION)
  168.         {
  169. // STG:
  170. //            token_action(curtok);
  171.             curtok = lex_stream -> Gettoken();
  172.             current_kind = lex_stream -> Kind(curtok);
  173.  
  174.             act -= ERROR_ACTION;
  175.         }
  176.         else if (act < ACCEPT_ACTION)
  177.         {
  178. // STG:
  179. //            token_action(curtok);
  180.             curtok = lex_stream -> Gettoken();
  181.             current_kind = lex_stream -> Kind(curtok);
  182.  
  183.             continue;
  184.         }
  185.         else break;
  186.  
  187.         //
  188.         // Process a non_terminal
  189.         //
  190.         do
  191.         {
  192.             state_stack_top -= (rhs[act] - 1);
  193.             (this ->* rule_action[act])();
  194.             act = nt_action(stack[state_stack_top], lhs[act]);
  195.         } while(act <= NUM_RULES);
  196.     } /* process_terminal */
  197.  
  198.     if (act == ERROR_ACTION)
  199.     {
  200.         //
  201.         // If any error is found in a package declaration, do not try to repair it.
  202.         //
  203.         if (! parse_package_header_only)
  204.             RepairParse(curtok);
  205.  
  206.         if (parse_stack[0] && parse_stack[0] -> CompilationUnitCast())
  207.             parse_stack[0] -> kind = Ast::BAD_COMPILATION;
  208.         else
  209.         {
  210. // STG:
  211. //            delete parse_stack[0];
  212.             parse_stack[0] = NULL;
  213.         }
  214.     }
  215.  
  216.     return parse_stack[0];
  217. }
  218.  
  219.  
  220. bool Parser::BodyParse(LexStream *lex_stream_, AstClassBody *class_body)
  221. {
  222. assert(class_body -> UnparsedClassBodyCast());
  223.  
  224.     lex_stream = lex_stream_;
  225.     ast_pool = class_body -> pool;
  226.     body_pool = class_body -> pool;
  227.     list_node_pool = new StoragePool(lex_stream_ -> NumTokens());
  228.     free_list_nodes = NULL;
  229.  
  230.     bool no_errors_detected = Body(class_body);
  231.  
  232.     delete list_node_pool; // free the pool of list nodes
  233.  
  234.     class_body -> mark_parsed();
  235.  
  236.     return no_errors_detected;
  237. }
  238.  
  239.  
  240. bool Parser::Body(AstClassBody *class_body)
  241. {
  242.     bool no_errors_detected = true;
  243.  
  244.     for (int i = 0; i < class_body -> NumConstructors(); i++)
  245.     {
  246.         AstConstructorDeclaration *constructor_decl = class_body -> Constructor(i);
  247.  
  248.         if (constructor_decl -> constructor_symbol)
  249.         {
  250.             AstConstructorBlock *block = constructor_decl -> constructor_body;
  251.             end_token = block -> right_brace_token; // last token in the body
  252.  
  253.             AstStatement *new_body = (AstStatement *) ParseSegment(block -> left_brace_token);
  254.  
  255.             if (! new_body)
  256.                 no_errors_detected = false;
  257.             else
  258.             {
  259.                 AstConstructorBlock *new_block = new_body -> ConstructorBlockCast();
  260.  
  261.                 if (! new_block)
  262.                 {
  263.                     new_block                                        = ast_pool -> GenConstructorBlock();
  264.                     new_block -> left_brace_token                    = new_body -> LeftToken();
  265.                     new_block -> explicit_constructor_invocation_opt = NULL;
  266.                     new_block -> block                               = (AstBlock *) new_body;
  267.                     new_block -> right_brace_token                   = new_body -> RightToken();
  268.                 }
  269. // STG:
  270. //                delete block; // destroy old empty block
  271. //
  272.                 constructor_decl -> constructor_body = new_block;
  273.             }
  274.         }
  275.     }
  276.  
  277.     for (int j = 0; j < class_body ->